package com.cmc6.common.util;

import com.cmc6.common.config.BaseConfig;
import com.cmc6.common.exception.BaseBizCodeEnum;
import com.cmc6.common.exception.BaseException;
import com.cmc6.common.exception.IBizCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * 建议：不要 new对象来设置属性值，这里写 @Data只是为了 feign调用时可以作为返回值，所以请把这个 @Data当成 @Getter来看待
 */
@Data
@ApiModel(description = "统一响应实体类")
public class ApiResult<T> {

    @ApiModelProperty(value = "响应代码，成功返回：200")
    private Integer code;

    @ApiModelProperty(value = "响应描述")
    private String msg;

    @ApiModelProperty(value = "服务器是否收到请求，只会给调用者返回 true")
    private boolean success = true;

    private T data;

    @ApiModelProperty(value = "服务名")
    private String service = BaseConfig.applicationName;

    public ApiResult() {
    }

    private ApiResult(Integer code, String msg, T data) {
        this.msg = msg;
        this.code = code;
        this.data = data;
    }

    private ApiResult<T> end() {
        throw new BaseException(this);
    }

    public void setSuccess(boolean success) {
        // 不允许修改 success的值
    }

    public void setService(String service) {
        // 不允许修改 service的值
    }

    public T getData() {
        return data;
    }

    /**
     * 业务异常
     */
    public static <T> void busError() {
        error(BaseBizCodeEnum.API_RESULT_BUSINESS_ERROR);
    }

    /**
     * 系统异常
     */
    public static <T> void sysError() {
        error(BaseBizCodeEnum.API_RESULT_SYS_ERROR);
    }

    /**
     * 异常基础方法，会记录服务名
     */
    public static <T> ApiResult<T> error(IBizCode iBizCode) {
        return new ApiResult<T>(iBizCode.getCode(), iBizCode.getMsg(), null).end();
    }

    /**
     * 异常基础方法，会记录服务名，并且可以携带 data
     */
    public static <T> ApiResult<T> error(IBizCode iBizCode, T data) {
        return new ApiResult<>(iBizCode.getCode(), iBizCode.getMsg(), data).end();
    }

    /**
     * 异常基础方法，会记录服务名
     */
    public static <T> ApiResult<T> error(String msg) {
        return new ApiResult<T>(BaseBizCodeEnum.API_RESULT_SYS_ERROR.getCode(), msg, null).end();
    }

    /**
     * 操作成功
     */
    public static <T> ApiResult<T> ok(String msg, T data) {
        return new ApiResult<>(BaseBizCodeEnum.API_RESULT_OK.getCode(), msg, data);
    }

    public static <T> ApiResult<T> ok(T data) {
        return new ApiResult<>(BaseBizCodeEnum.API_RESULT_OK.getCode(), BaseBizCodeEnum.API_RESULT_OK.getMsg(), data);
    }

    public static <T> ApiResult<T> ok(String msg) {
        return new ApiResult<>(BaseBizCodeEnum.API_RESULT_OK.getCode(), msg, null);
    }

}
